﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LL.Utility.WindowsForms
{
    public class TreeViewHelper
    {
        public TreeView TreeView { get; set; }

        public TreeViewHelper(TreeView treeView)
        {
            this.TreeView = treeView;
        }

        #region Drag

        public void HandleDragDrop()
        {
            TreeView.ItemDrag += new ItemDragEventHandler(ItemDrag);
            TreeView.DragEnter += new DragEventHandler(DragEnter);
            TreeView.DragDrop += new DragEventHandler(DragDrop);
        }

        private void ItemDrag(object sender, ItemDragEventArgs e)
        {
            var tn = e.Item as TreeNode;
            var isExpand = tn.IsExpanded;
            tn.Collapse();
            if ((e.Button == MouseButtons.Left) && (tn != null))
            {
                var treeView = sender as TreeView;
                if (treeView != null)
                    treeView.DoDragDrop(tn,
                          DragDropEffects.Copy
                        | DragDropEffects.Move
                        | DragDropEffects.Link);
            }
            if (isExpand)
                tn.Expand();
        }
        private void DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode"))
            {
                e.Effect = DragDropEffects.Move;
                return;
            }
            e.Effect = DragDropEffects.None;
        }
        private void DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                var pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
                var destinationNode = ((TreeView)sender).GetNodeAt(pt);
                var node = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
                if (destinationNode == null || destinationNode == node || node.Parent == destinationNode)
                    return;
                if (destinationNode.FullPath.Contains(node.FullPath))
                    return;

                if (DropCompleted != null)
                {
                    var arg = new DropCompleateArgs()
                    {
                        DestinationNode = destinationNode,
                        SourceNode = node
                    };
                    DropCompleted(TreeView, arg);
                    if (arg.Cancel)
                        return;
                }
                destinationNode.Nodes.Add((TreeNode)node.Clone());
                destinationNode.Expand();
                node.Remove();
            }
        }

        public class TreeViewSettings
        {
            public bool RightClickSelect { get; set; }
            public bool EnableDrag { get; set; }
        }

        public delegate void DropCompletedEventHandler(object sender, DropCompleateArgs args);
        public event DropCompletedEventHandler DropCompleted;

        #endregion

        #region CheckBox

        public void EnableCheckAll()
        {
            //TreeView.
            TreeView.AfterCheck += new TreeViewEventHandler(TreeView_AfterCheck);
        }

        void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.Unknown)
                return;
            ChangeParentCheckState(e);
            ChangeSubCheckState(e.Node);
        }

        private void ChangeParentCheckState(TreeViewEventArgs e)
        {
            TreeNode node = e.Node.Parent;
            if (node == null)
                return;
            var checkedItems = from TreeNode d in node.Nodes
                               where d.Checked
                               select d;
            var count = node.Nodes.Count - checkedItems.Count();

            node.Checked = count == 0;
        }

        private static void ChangeSubCheckState(TreeNode node)
        {
            foreach (TreeNode subNode in node.Nodes)
            {
                subNode.Checked = node.Checked;
                ChangeSubCheckState(subNode);
            }
        }

        #endregion

        public TreeNode FindNodeOnPath(string nodepath)
        {
            return FindNodeOnPath(this.TreeView.Nodes, nodepath);
        }

        public static TreeNode FindNodeOnPath(TreeNodeCollection tn, string nodepath)
        {
            string str1 = null;
            string str2 = null;
            if (tn.Count < 1)
                return null;
            TreeNode TempTn = null;
            int pos = nodepath.IndexOf('\\', 0);
            if (pos > 0)
            {
                //当前要找的结点  
                str1 = nodepath.Substring(0, pos);
                //下一级目录的结点  
                str2 = nodepath.Substring(pos + 1);
            }
            else
                str1 = nodepath;
            //从当前一级树目录中查找结点  
            for (int i = 0; i < tn.Count; i++)
            {
                //找到了  
                if (tn[i].Text == str1)
                {
                    TempTn = tn[i];
                    //是要找树结点的最终位置  
                    if (str2 == null)
                        break;
                    else
                    {
                        //继续往下查找  
                        TreeNode tnd = FindNodeOnPath(tn[i].Nodes, str2);
                        if (tnd != null)
                            TempTn = tnd;
                    }
                    break;
                }
            }
            //没找到返回空 
            if (TempTn != null)
            {
                if (TempTn.Parent != null)
                    TempTn.Parent.Expand();
            }
            return TempTn;
        }
    }
}
